﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace Common
{
    /// <summary>
    /// 工作者线程输出委托
    /// </summary>
    /// <param name="message"></param>
    public delegate void SingleWorkerLoggerOutput(string message);

    /// <summary>
    /// 单例任务
    /// </summary>
    public abstract class SingleWorker
    {
        /// <summary>
        /// 单例任务
        /// </summary>
        /// <param name="workerName"></param>
        protected SingleWorker(string workerName)
        {
            WorkerName = workerName;
        }
        #region Property
        /// <summary>
        /// 日志对象
        /// </summary>
        public SingleWorkerLoggerOutput Logger { get; set; }

        /// <summary>
        /// 工作状态
        /// </summary>
        public WorkerStatus Status { get; private set; }

        /// <summary>
        /// 当前线程
        /// </summary>
        private Thread RunThread { get; set; }

        /// <summary>
        /// 任务名称
        /// </summary>
        protected string WorkerName { get; private set; }

        #endregion

        #region 控制线程
        /// <summary>
        /// 开启工作
        /// </summary>
        public void Start()
        {
            if (Status == WorkerStatus.Start)
                return;
            Output("Start Worker");
            Status = WorkerStatus.Start;
            RunThread = new System.Threading.Thread(() =>
            {
                try
                {
                    Working();
                }
                catch (Exception ex)
                {
                    Output(ex);
                }
                //避免子类不关闭
                Stop();
            });
            RunThread.Name = WorkerName;
            RunThread.Start();
        }

        /// <summary>
        /// 停止工作
        /// </summary>
        public void Stop()
        {
            if (Status == WorkerStatus.Stop)
                return;
            try
            {
                Status = WorkerStatus.Stop;
                Output("Stop Worker");
                RunThread.Abort();
            }
            catch
            {
            }
        }

        /// <summary>
        /// 暂停工作
        /// </summary>
        /// <param name="millisecondsTimeout"></param>
        public void Sleep(int millisecondsTimeout)
        {
            Status = WorkerStatus.Sleep;
            Output("Sleep Worker " + millisecondsTimeout / 1000 + "秒");
            Thread.Sleep(millisecondsTimeout);
        }
        #endregion

        #region abstract

        /// <summary>
        /// 监听
        /// </summary>
        protected abstract void Working();

        /// <summary>
        /// 输出消息
        /// </summary>
        /// <param name="message">消息</param>
        protected void Output(string message)
        {
            Logger?.Invoke($"{WorkerName}:{message}");
        }
        /// <summary>
        /// 输出错误信息
        /// </summary>
        /// <param name="ex"></param>
        protected void Output(Exception ex)
        {
            string message = $"{WorkerName}：异常 > {ex.Message} {ex.StackTrace}";
            Logger?.Invoke(message);
        }
        #endregion

        /// <summary>
        /// <![CDATA[
        /// 1.后续采用WorkerContext来批量管理监听；
        /// 2.子类只需要指定定时间隔或者函数即可；
        /// 3.采用服务注册、批量开、关、注销等功能；
        /// ]]>
        /// </summary>
        public enum WorkerStatus
        {
            /// <summary>
            /// 已打开监听中
            /// </summary>
            Start = 1,
            /// <summary>
            /// 监听已关闭
            /// </summary>
            Stop = 2,
            /// <summary>
            /// 监听休眠中
            /// </summary>
            Sleep = 3,
        }
    }


}
